#include "VS1stCameraController.h"
#include "VSCamera.h"
#include "VSQuat.h"
#include "VSGraphicInclude.h"
#include "VSStream.h"
using namespace VSEngine2;
IMPLEMENT_RTTI(VS1stCameraController,VSController)
static bool gs_bStreamRegistered_VS1stCameraController = VS1stCameraController::RegisterMainFactory ();
bool VS1stCameraController::ms_bRegisterMainFactory = false;
bool VS1stCameraController::RegisterMainFactory()
{
	if (!ms_bRegisterMainFactory)
	{ 
		VSMain::AddInitialFuntion(VS1stCameraController::InitialClassFactory); 
		ms_bRegisterMainFactory = true;
	} 
	return ms_bRegisterMainFactory;

}
bool VS1stCameraController::InitialClassFactory()
{
	ms_ClassFactory.AddElement(ms_Type.GetName(),FactoryFunc);
	
	return 1;
}
VSObject * VS1stCameraController::FactoryFunc()
{
	return VS_NEW VS1stCameraController;


}
VS1stCameraController::VS1stCameraController()
{
	m_RotXDelta = 0.0f;
	m_RotYDelta = 0.0f;
	m_MoveXDelta = 0.0f;
	m_MoveYDelta = 0.0f;
	m_MoveZDelta = 0.0f;
}
VS1stCameraController:: ~VS1stCameraController()
{

}
bool VS1stCameraController::UpdateEx(double dAppTime)
{
	if(!VSController::UpdateEx(dAppTime))
		return 0;


	//VSFreeCamera * Temp = (VSFreeCamera *)m_pObject;

	VSCamera* Temp = DynamicCast<VSCamera>(m_pObject);
	if(!Temp)
		return 0;
	Temp->m_RotX += m_RotXDelta * (VSREAL)m_dIntervalTime;
	Temp->m_RotY += m_RotYDelta * (VSREAL)m_dIntervalTime;
	Temp->m_RotZ  = 0;

	if (Temp->m_RotX > 1.4707963f) Temp->m_RotX = 1.4707963f;
	else if (Temp->m_RotX < -1.4707963f) Temp->m_RotX = -1.4707963f;

	if (Temp->m_RotY > VS2PI) Temp->m_RotY -= VS2PI;
	else if (Temp->m_RotY < -VS2PI) Temp->m_RotY += VS2PI;


	VSVector3 LocalPos = Temp->GetLocalTranslate();
	VSMatrix3X3 Rot = Temp->GetLocalRotate();
	VSVector3 Velocity(m_MoveXDelta,m_MoveYDelta,m_MoveZDelta);
	LocalPos += Velocity * Rot * (VSREAL)m_dIntervalTime;

	VSQuat    qFrame(0,0,0,1);			

	qFrame.CreateEuler(Temp->m_RotX, Temp->m_RotY, Temp->m_RotZ);

	VSMatrix3X3 Mat;
	Mat.Identity();
	qFrame.GetMatrix(Mat);

	Temp->SetLocalRotate(Mat);
	Temp->SetLocalTranslate(LocalPos);

	return 1;
}

unsigned int VS1stCameraController::DiskUse()const
{
	unsigned int Use = VSController::DiskUse();

	Use += sizeof(VSREAL) * 5;

	return Use;

}
bool VS1stCameraController::Save(VSStream & rStream,unsigned int &iSaveUse)const
{
	if(!VSController::Save(rStream,iSaveUse))
		return 0;


	if(!rStream.Write(&m_RotXDelta,sizeof(VSREAL)))
		return 0;
	iSaveUse +=sizeof(VSREAL);

	if(!rStream.Write(&m_RotYDelta,sizeof(VSREAL)))
		return 0;
	iSaveUse +=sizeof(VSREAL);


	if(!rStream.Write(&m_MoveXDelta,sizeof(VSREAL)))
		return 0;
	iSaveUse +=sizeof(VSREAL);

	if(!rStream.Write(&m_MoveYDelta,sizeof(VSREAL)))
		return 0;
	iSaveUse +=sizeof(VSREAL);

	if(!rStream.Write(&m_MoveZDelta,sizeof(VSREAL)))
		return 0;
	iSaveUse +=sizeof(VSREAL);
	return 1;
}
bool VS1stCameraController::Load(VSStream & rStream,unsigned int &iSaveUse)
{
	if(!VSController::Load(rStream,iSaveUse))
		return 0;

	if(!rStream.Read(&m_RotXDelta,sizeof(VSREAL)))
		return 0;
	iSaveUse +=sizeof(VSREAL);

	if(!rStream.Read(&m_RotYDelta,sizeof(VSREAL)))
		return 0;
	iSaveUse +=sizeof(VSREAL);


	if(!rStream.Read(&m_MoveXDelta,sizeof(VSREAL)))
		return 0;
	iSaveUse +=sizeof(VSREAL);

	if(!rStream.Read(&m_MoveYDelta,sizeof(VSREAL)))
		return 0;
	iSaveUse +=sizeof(VSREAL);

	if(!rStream.Read(&m_MoveZDelta,sizeof(VSREAL)))
		return 0;
	iSaveUse +=sizeof(VSREAL);
	return 1;
}
bool VS1stCameraController::Clone(const VSObject *pObject,unsigned int uiType)
{
	const VS1stCameraController* Temp = DynamicCast<VS1stCameraController>(pObject); 
	if(!Temp)
		return 0;
	if(VSController::Clone(pObject,uiType))
	{

		m_RotXDelta = Temp->m_RotXDelta;
		m_RotYDelta = Temp->m_RotYDelta;
		m_MoveXDelta = Temp->m_MoveXDelta;
		m_MoveYDelta = Temp->m_MoveYDelta;
		m_MoveZDelta = Temp->m_MoveZDelta;
		return 1;
	}
	else
	{
		return 0;

	}


}